package sistemaEnemigo;

import escenario.Escenario;
import escenario.IdPosEnemigo;
import escenario.Misil;
import escenario.Posicion;
import java.lang.StrictMath;

public class MisilEnemigo extends Misil {
	
	private IdPosEnemigo PE = new IdPosEnemigo();
	private boolean alive = true;

	public MisilEnemigo(Escenario es){
		this.setEscenario(es);
		es.addMisilEnemigo(this);
	}

	public IdPosEnemigo getPE() {
		return PE;
	}

	public void addPosAbs(){
		PE.setId(this.getId());
		PE.setX(this.getXAbs());
		PE.setY(this.getYAbs());
		PE.setZ(this.getPosicion().getZ());		
		this.getEscenario().addPosEnemigo(PE);
	}
	
	public void setPosAbs(){
		PE.setX(this.getXAbs());
		PE.setY(this.getYAbs());
		PE.setZ(this.getPosicion().getZ());		
		this.getEscenario().setPosEnemigo(PE.getId(), PE);
	}
	
	public boolean isAlive() {
		return alive;
	}

	public void setAlive(boolean alive) {
		this.alive = alive;
	}
	
	public void mover(){
		this.getPosicion().setRadio(this.getPosicion().getRadio() - 1);
		this.setPosAbs();
	}
	
	/**
	 * metodo en evaluacion por incongruencias en el movimiento de los misiles sobre los ejes.
	 * el signo en el teorema del coseno deberia variar dependiendo del cuadrante en donde se lo calcula
	 */
	
	private double radioTrayectoria(){
		double a, b, c;
		double alfa=this.getPosicion().getTita();	System.out.println("alfa: " + alfa);
		
		
		a=this.getPosicion().getRadio();	System.out.println("a: " + a);
		b=this.getDestino().getRadio();		System.out.println("b: " + b);
		c=StrictMath.sqrt(a * a + b * b - 2 * a * b * StrictMath.cos((StrictMath.PI / 2) + alfa)); //cambio de signo?
		
		
		System.out.println("c: " + c);
		return c;
	}
	/**
	 * metodo que calcula el radio de trayectoria a traves de la 
	 * distancia entre el punto de origen y el punto de destino
	 * 
	 * @return
 	 */
	private double radioTrayectoria1(){
		double DISTANCIA, r1, r2;
		double x1,y1,z1,x2,y2,z2;
		double x, y, z;
		
		r1 = this.getPosicion().getRadio();	
		r2 = this.getDestino().getRadio();	
		
		x1 = r1*StrictMath.sin(this.getPosicion().getTita())*StrictMath.cos(this.getPosicion().getFi());
		x1 = (StrictMath.sin(this.getPosicion().getTita()) * r1 * StrictMath.cos(this.getPosicion().getFi()));
		y1 = r1*StrictMath.sin(this.getPosicion().getTita())*StrictMath.sin(this.getPosicion().getFi());
		z1 = r1*StrictMath.cos(this.getPosicion().getTita());
		/*
		System.out.println("fi: " + this.getPosicion().getFi()); 
		System.out.println("tita: " + this.getPosicion().getTita());
		System.out.println("R1: " + r1);
		System.out.println("R2: " + r2);
		
		System.out.println("x1: " + x1);
		System.out.println("y1: " + y1);
		System.out.println("z1: " + z1);*/
		
		x2 = r2*StrictMath.sin(this.getDestino().getTita())*StrictMath.cos(this.getDestino().getFi());
		y2 = r2*StrictMath.sin(this.getDestino().getTita())*StrictMath.sin(this.getDestino().getFi());
		z2 = r2*StrictMath.cos(this.getDestino().getTita());
		/*
		System.out.println("x2: " + x2);
		System.out.println("y2: " + y2);
		System.out.println("z2: " + z2);
		*/
		x = (x2-x1);
		y = (y2-y1);
		z = (z2-z1);
		/*
		System.out.println("x2-x1: " + x);
		System.out.println("y2-y1: " + y);
		System.out.println("z2-z1: " + z);
		*/
		DISTANCIA = StrictMath.sqrt(StrictMath.pow(x, 2) + StrictMath.pow(y, 2) + StrictMath.pow(z, 2)); 
		System.out.println("DISTANCIA"+ this.getId() + ": " + DISTANCIA);
		return DISTANCIA;
	}
	/**
	 * 
	 */
	
	
	/**
	 * metodo en evaluacion por incongruencias en el movimiento de los misiles sobre los ejes.
	 * todavia no se encuentra el error.
	 */
	
	private double titaTrayectoria(double rN){
		double radioNuevo, titaViejo, radioDestino, beta, alfa;
		radioNuevo=rN; 		//System.out.println("rN: " + radioNuevo);
		titaViejo=this.getPosicion().getTita();		//System.out.println("titaViejo: " + titaViejo);
		radioDestino=this.getDestino().getRadio();	//System.out.println("radioDestino: " + radioDestino);
		
		beta=StrictMath.asin(radioDestino * (StrictMath.sin((StrictMath.PI / 2) - titaViejo)) / radioNuevo); //System.out.println("beta: " + beta);	
		alfa = StrictMath.PI - ((StrictMath.PI / 2) - titaViejo) - beta; System.out.println("alfa: " + alfa);	
		
		alfa = alfa - (StrictMath.PI / 2);	System.out.println("alfa2: " + alfa);	
		
		return alfa;
		
	}
	/**
	 * metodo nuevo
	 * 
	 */
	private double titaTrayectoria2(double rN){
		double a1,b1,c1, error = -1000;
		double alfa, beta, gamma, tetha;
		
		beta = (StrictMath.PI/2) + this.getPosicion().getTita();
		a1 = this.getDestino().getRadio();
		b1 = rN;
		c1 = this.getPosicion().getRadio()*StrictMath.sin(this.getPosicion().getTita());
//		/*
		System.out.println("a1: " + a1);
		System.out.println("beta: " + beta);
		System.out.println("b1: " + b1);
//		*/
//		alfa = StrictMath.asin(a1*(StrictMath.sin(beta)/b1));
		
		if(a1 >= b1){
			double num, den;   //     num / den
			
			num = StrictMath.pow(a1, 2) - StrictMath.pow(b1, 2) - StrictMath.pow(c1, 2);
			
			den = -2*b1*c1;
			
			alfa = StrictMath.acos(num/den);
			beta = StrictMath.asin(a1*(StrictMath.sin(beta)/b1));	//teorema del seno
			
			gamma = StrictMath.PI - alfa - beta;
			tetha = StrictMath.PI/2 - gamma;
//			/*
			System.out.println("alfa>=: " + alfa);
			System.out.println("gamma>=: " + gamma);
			System.out.println("tetha>=: " + tetha);
//			*/
			return tetha;
		}
		
		if(a1 < b1){
			double num, den;   //     num / den
			
			num = StrictMath.pow(b1, 2) - StrictMath.pow(a1, 2) - StrictMath.pow(c1, 2);
			
			den = -2*a1*c1;
			
			beta = StrictMath.acos(num/den);
			alfa = StrictMath.asin(a1*(StrictMath.sin(beta)/b1));	//teorema del seno
			
			gamma = StrictMath.PI - alfa - beta;
			tetha = StrictMath.PI/2 - gamma;
//			/*
			System.out.println("alfa<: " + alfa);
			System.out.println("gamma<: " + gamma);
			System.out.println("tetha<: " + tetha);
//			*/
			return tetha;
		}
		
		
		
		return error;
	}
	/**
	 * metodo en evaluacion por incongruencias en el movimiento de los misiles sobre los ejes.
	 */
	
	
	private void cambiarEje(){
		double radioNuevo=this.radioTrayectoria1();
		double titaNuevo=this.titaTrayectoria2(radioNuevo);
		this.getPosicion().setTita(titaNuevo);
		this.getPosicion().setRadio(radioNuevo);
	}
	
	
	/**
	 * 
	 */
	
	
	public void colision(MisilEnemigo misilImpactado){
		System.out.println("Misil " + this.getId() 
				+ " impacto al misil " + misilImpactado.getId() );
		
		this.getEscenario().setMisilEnemigo(this.getId(), null);
		this.getEscenario().setPosEnemigo(this.getId(), null);
		
		this.getEscenario().setMisilEnemigo(misilImpactado.getId(), null);
		this.getEscenario().setPosEnemigo(misilImpactado.getId(), null);
		
		this.setAlive(false);
		misilImpactado.setAlive(false);
	}
	
	public void run(){
		System.out.println("Se ejecuto el misil enemigo: " + this.getId());
		this.setPosicionAbsoluta();
		this.cambiarEje();

		while(this.getPosicion().getRadio() > 0 && this.isAlive()){
			this.mover();
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
		}
	}	
	
}